from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnableConfig
from pydantic import Field

from application.base_mcp_v1.excel_mcp_tool import excel_to_json_array_tool
from application.base_mcp_v1.family_bucket_mcp_tool import scan_all_family_bucket_to_config_item, \
    construct_family_bucket_chain
from infrastructure.utils.process import timer_context

result_no_matched_prompt_template = """\n## 配置项{{index}}: {{item_name}}
- 是否可复用全家桶: {{matched}}

- 配置项结构: {{table}}

"""

result_matched_prompt_template = result_no_matched_prompt_template + """- 铜雀台全家桶结构体定义: {{tqt_structs}}

- 服务端全家桶结构体定义: {{svr_structs}}
\n
"""


class PromptGenerator:
    """
    提示词生成器
    """

    def __init__(self):
        self.prompt = ''

    def append(self, input: dict, template: str):
        self.prompt += PromptTemplate.from_template(template=template, template_format="jinja2").invoke(
            input).to_string()

    def to_prompt_string(self):
        return self.prompt


def split_json_array_to_config_items(json_array: list[list]) -> list[dict[str, list]]:
    """
    将JSON二维数组拆分成每个单独的配置项
    """
    result = []
    item_dict = {}
    item_config = []
    for row in json_array:
        # 配置项内容
        if len(row) > 1:
            item_config.append(row)
        # 配置项表头或者分隔行
        else:
            item_header = row[0]
            # 表头
            if item_header:
                item_dict['item_header'] = item_header
                item_config.append(row)
            # 分割行
            else:
                item_dict['item_config'] = item_config
                result.append(item_dict)
                # clear 重置
                item_dict = {}
                item_config = []
    return result


def excel_to_struct_tool(
        excel_file_path: str = Field(..., description='excel文件绝对路径')
):
    # 从excel文件中读取JSON二维数组
    json_array = excel_to_json_array_tool(excel_file_path)
    # JSON拆分成每个单独的配置项
    config_item_list = split_json_array_to_config_items(json_array)
    # 扫描所有全家桶配置项
    all_config_item = scan_all_family_bucket_to_config_item()
    inputs = []
    # 每个配置项分别调用family_bucket_tool
    for config_item in config_item_list:
        inputs.append({
            'all_config_item': all_config_item,
            'config_item': config_item['item_config']
        })
    # 构造chain
    chain = construct_family_bucket_chain()
    # 批量调用
    with timer_context('family_bucket_tool'):
        results = chain.batch(inputs=inputs, config=RunnableConfig(max_concurrency=8 * 2))
    generator = PromptGenerator()
    for index, result in enumerate(results):
        print(f'the {index + 1} times calling...')
        input_dict = {
            'index': index + 1,
            **result,
        }
        if result.get('matched'):
            generator.append(input=input_dict, template=result_matched_prompt_template)
        else:
            generator.append(input=input_dict, template=result_no_matched_prompt_template)
    return generator.to_prompt_string()


if __name__ == '__main__':
    print(excel_to_struct_tool('D:\\Code_Python\\activity_demo\\test\\全家桶.xlsx'))
    # prompt = PromptGenerator()
    # prompt.append({
    #     "index": 1,
    #     "item_name": "礼包配置1",
    #     "matched": True,
    #     "tqt_structs": [
    #         "type TqtPackageStoreV2 struct {\n\tTypName          string  `json:\"typName\" header:\"礼包类型\" allowEmpty:\"true\"`                        // 礼包类型名称\n\tTyp              int     `json:\"typ\" skipField:\"true\" validate:\"gte=0\"`                          // 礼包类型\n\tNo               int     `json:\"no\" header:\"编号\" validate:\"gt=0\"`                                 // 编号\n\tPackageName      string  `json:\"packageName\" header:\"礼包名称\" validate:\"required\"`                  // 礼包名称\n\tCurrency         string  `json:\"currency\" header:\"货币种类\" validate:\"required\"`                     // 货币种类\n\tCurrencyCount    int     `json:\"currencyCount\" header:\"货币数量\" allowEmpty:\"true\" validate:\"gte=0\"` // 货币数量\n\tLogicalProductId string  `json:\"logicalProductId\" header:\"购买项id\" allowEmpty:\"true\"`              // 购买项id\n\tPrice            float64 `json:\"price\" header:\"价格\" allowEmpty:\"true\" validate:\"gte=0\"`           // 价格\n\tStartDay         int     `json:\"startDay\" header:\"第几天开始\" validate:\"gt=0\"`                        // *第几天结束和第几天开始的填写值需要>0； *第几天结束≥第几天开始(validate)\n\tEndDay           int     `json:\"endDay\" header:\"第几天结束\" validate:\"gt=0\"`                          // *第几天结束和第几天开始的填写值需要>0； *第几天结束≥第几天开始(validate)\n\tStartTime        TqtTime `json:\"startTime\" header:\"开始时间\" validate:\"required\"`                    // *开始时间和结束时间需填写时间格式：时：分：秒\n\tEndTime          TqtTime `json:\"endTime\" header:\"结束时间\" validate:\"required\"`                      // *开始时间和结束时间需填写时间格式：时：分：秒\n\tValue            int     `json:\"value\" header:\"价值千分比\" allowEmpty:\"true\" validate:\"gte=0\"`\n\tBuyLimit         int     `json:\"buyLimit\" header:\"限购次数\" validate:\"gt=0\"`\n\tIsDailyReset     bool    `json:\"isDailyReset\" header:\"是否每日重置\" true:\"是\" false:\"否\"`\n}"
    #     ],
    #     "svr_structs": [
    #         "type SvrPackageStoreV2 struct {\n\tNo           int      `json:\"no\"`             // 编号\n\tAward        SvrAward `json:\"award\"`          // 商品，id填礼包的gId\n\tPrice        SvrAward `json:\"price\"`          // 价格\n\tTyp          int      `json:\"typ\"`            // 类型 查询接口：https://xmdc.yuque.com/hgngvk/dvagbh/fryh5a8ahcniuihc#maQYW\n\tValue        int      `json:\"value\"`          // 价值千分比分子\n\tBuyLimit     int      `json:\"buy_limit\"`      // 限购，-1表示无限\n\tStartOffset  int      `json:\"start_offset\"`   // 开始时间，距活动开始时间毫秒数\n\tEndOffset    int      `json:\"end_offset\"`     // 结束时间，距活动开始时间毫秒数\n\tIsDailyReset bool     `json:\"is_daily_reset\"` // 是否每日重置\n}"
    #     ],
    #     "table": "[[\"礼包配置1\"], [\"礼包类型\", \"编号\", \"礼包名称\", \"货币种类\", \"货币数量\", \"购买项id\", \"价格\", \"第几天开始\", \"第几天结束\", \"开始时间\", \"结束时间\", \"价值千分比\", \"限购次数\", \"是否每日重置\"], [\"糖果屋\", 1, \"糖果屋1级礼包\", \"食物\", 100, \"\", \"\", 1, 2, \"00:00:00\", \"23:59:59\", 28000, 1, \"否\"], [\"糖果屋\", 2, \"糖果屋2级礼包\", \"金币\", 50, \"\", \"\", 3, 4, \"00:00:00\", \"23:59:59\", 27000, 1, \"否\"]]"
    # }, result_matched_prompt_template)
    # prompt.append({
    #     "index": 2,
    #     "item_name": "礼包配置2",
    #     "matched": False,
    #     "table": "[[\"礼包配置2\"], [\"礼包类型\", \"编号\", \"礼包名称\", \"货币种类\", \"货币数量\", \"购买项id\", \"价格\", \"第几天开始\", \"第几天结束\", \"开始时间\", \"结束时间\", \"价值千分比\", \"限购次数\", \"是否每日重置\"], [\"糖果屋\", 1, \"糖果屋1级礼包\", \"食物\", 100, \"\", \"\", 1, 2, \"00:00:00\", \"23:59:59\", 28000, 1, \"否\"], [\"糖果屋\", 2, \"糖果屋2级礼包\", \"金币\", 50, \"\", \"\", 3, 4, \"00:00:00\", \"23:59:59\", 27000, 1, \"否\"]]"
    # }, result_no_matched_prompt_template)
    # print(prompt.to_prompt_string())
